package com.itheima.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itheima.common.exception.NcException;
import com.itheima.common.exception.enums.ResponseEnum;
import com.itheima.common.threadlocal.UserHolder;
import com.itheima.common.util.BeanHelper;
import com.itheima.common.util.JsonUtils;
import com.itheima.common.vo.UserInfo;
import com.itheima.sys.dto.SysFunctionDTO;
import com.itheima.sys.dto.SysRoleDTO;
import com.itheima.sys.dto.SysRoleEditDTO;
import com.itheima.sys.entity.SysFunction;
import com.itheima.sys.entity.SysRole;
import com.itheima.sys.entity.SysRoleFunction;
import com.itheima.sys.mapper.SysRoleMapper;
import com.itheima.sys.service.ISysFunctionService;
import com.itheima.sys.service.ISysRoleFunctionService;
import com.itheima.sys.service.ISysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 角色表  服务实现类
 * </p>
 *
 * @author itheima
 * @since 2020-12-13
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    @Autowired
    private ISysFunctionService functionService;

    @Autowired
    private ISysRoleFunctionService roleFunctionService;


    @Override
    public List<SysRoleDTO> queryRoles(Long companyUserId, Long companyId) {
        List<SysRole> roleList = this.getBaseMapper().queryRoles(companyUserId, companyId);
        if(!roleList.isEmpty()){
            return BeanHelper.copyWithCollection(roleList, SysRoleDTO.class);
        }
        return null;
    }

    @Override
    public List<SysRoleDTO> queryRolesByCompanyId() {
        //如何获取当前企业ID
        Long companyId = UserHolder.getCompanyId();
        //1.先查询当前企业角色
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysRole::getCompanyId, companyId);
        List<SysRole> sysRoleList = this.list(queryWrapper);
        if(sysRoleList.isEmpty()){
            throw new NcException(ResponseEnum.ROLE_NOT_FOUND);
        }
        List<SysRoleDTO> sysRoleDTOList = BeanHelper.copyWithCollection(sysRoleList, SysRoleDTO.class);
        //设置每个角色中包含权限列表
        for (SysRoleDTO sysRoleDTO : sysRoleDTOList) {
            Long roleId = sysRoleDTO.getId();
            //根据角色ID查询角色包含权限
            List<SysFunction> functionList = functionService.queryFunctionsByRoleId(roleId, companyId);
            if(!functionList.isEmpty()){
                sysRoleDTO.setSysFunctionAbbrList(BeanHelper.copyWithCollection(functionList, SysFunctionDTO.class));
            }
        }
        return sysRoleDTOList;
    }

    @Override
    @Transactional
    public void updateRole(SysRoleEditDTO sysRoleEditDTO) {
        //1.修改角色信息
        SysRole sysRole = BeanHelper.copyProperties(sysRoleEditDTO, SysRole.class);
        boolean b = this.updateById(sysRole);
        if(!b){
            throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
        }
        //2.删除中间表中角色旧的权限（前提：角色关联权限）
        //2.1 先根据角色ID 查询角色权限中间表中是否有记录
        QueryWrapper<SysRoleFunction> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysRoleFunction::getRoleId, sysRole.getId());
        int count = roleFunctionService.count(queryWrapper);
        if(count>0){
            boolean b1 = roleFunctionService.remove(queryWrapper);
            if(!b1){
                throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
            }
        }
        //3.新增角色对应权限关系
        if(!sysRoleEditDTO.getFunctionIdList().isEmpty()){
            ArrayList<SysRoleFunction> sysRoleFunctions = new ArrayList<>();
            for (Long functionId : sysRoleEditDTO.getFunctionIdList()) {
                SysRoleFunction sysRoleFunction = new SysRoleFunction();
                sysRoleFunction.setFunctionId(functionId);
                sysRoleFunction.setRoleId(sysRole.getId());
                sysRoleFunctions.add(sysRoleFunction);
            }
            boolean b2 = roleFunctionService.saveBatch(sysRoleFunctions);
            if(!b2){
                throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
            }
        }
    }

    @Override
    public SysRole querySysAdminRole(Long companyId) {
        QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
        sysRoleQueryWrapper.lambda().eq(SysRole::getCompanyId, companyId);
        sysRoleQueryWrapper.lambda().eq(SysRole::getRoleName, "ROLE_ADMIN_SYS");
        SysRole one = this.getOne(sysRoleQueryWrapper);
        return one;
    }
}
